<ui:composition xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:p="http://primefaces.org/ui"
	template="../templates/ui.xhtml">
    
    <ui:define name="head">
        <style type="text/css">
            .messageInput {
                width:400px;
            }
            
            .publicColumn {
               width:80%;
            }
            
            .usersColumn {
                width:20%;
            }
            
            .vtop {
                vertical-align: top;
            }
            
            .chatlogs {
                height:200px;
                overflow:auto;
                padding: 0.5em 1em 0.5em 0.5em;
            }
            
            .usersList {
                height:200px;
                overflow:auto;
            }
            
            .usersList ul {
                list-style-type: none;
                padding-left:10px;
            }
            
            .usersList ul li {
                margin-bottom: 2px;
            }
            
            .usersList .ui-button-text {
                padding:0;
            }
        </style>
        
        <script type="text/javascript">
            //<![CDATA[
            function handleMessage(data) {
                var chatContent = $(PrimeFaces.escapeClientId('form:public'));
                chatContent.append(data + '<br />');
                
                //keep scroll
                chatContent.scrollTop(chatContent.height());
            }
            //]]>
        </script>
    </ui:define>

	<ui:define name="content">

			<h1 class="title ui-widget-header ui-corner-all">PrimePush - Chat</h1>
			<div class="entry">
			<p>Chat is a simple push based application created with PrimePush.</p>
            
            <p:growl id="growl" showDetail="true" />
            
            <h:form id="form">
                
                <p:fieldset id="container" legend="PrimeChat" toggleable="true">
                    
                    <h:panelGroup rendered="#{chatView.loggedIn}">
                        
                        <h:panelGrid columns="2" columnClasses="publicColumn,usersColumn" style="width:100%">
                            <p:outputPanel id="public" layout="block" styleClass="ui-corner-all ui-widget-content chatlogs"/>
                            
                            <p:dataList id="users" var="user" value="#{chatUsers.users}" styleClass="usersList">
                                <f:facet name="header">
                                    Users
                                </f:facet>

                                <p:commandButton title="Chat" icon="ui-icon-comment" oncomplete="PF('pChat').show()" update=":form:privateChatContainer">
                                    <f:setPropertyActionListener value="#{user}" target="#{chatView.privateUser}" />
                                </p:commandButton>
                                #{user}
                            </p:dataList>
                        </h:panelGrid>
                        
                        <p:separator />
                        
                        <p:inputText value="#{chatView.globalMessage}" styleClass="messageInput" />
                        <p:spacer width="5" />
                        <p:commandButton value="Send" actionListener="#{chatView.sendGlobal}" oncomplete="$('.messageInput').val('').focus()"/>
                        <p:spacer width="5" />
                        <p:commandButton value="Disconnect" actionListener="#{chatView.disconnect}" global="false" update="container" />
                    </h:panelGroup>
                    
                    <h:panelGroup rendered="#{not chatView.loggedIn}" >
                        Username: <p:inputText value="#{chatView.username}" />
                
                        <p:spacer width="5" />
                        <p:commandButton value="Login" actionListener="#{chatView.login}" update="container" 
                                         icon="ui-icon-person" />
                    </h:panelGroup>
                    
                </p:fieldset>
                
                <p:dialog widgetVar="pChat" header="Private Chat" modal="true" showEffect="fade" hideEffect="fade">
                    <h:panelGrid id="privateChatContainer" columns="2" columnClasses="vtop,vtop">
                        <p:outputLabel for="pChatInput" value="To: #{chatView.privateUser}" />
                        <p:inputTextarea id="pChatInput" value="#{chatView.privateMessage}" rows="5" cols="30" />
                        
                        <p:spacer />
                        <p:commandButton value="Send" actionListener="#{chatView.sendPrivate}" oncomplete="PF('pChat').hide()" />
                    </h:panelGrid>
                </p:dialog>
                             
            </h:form>
            
            <p:socket onMessage="handleMessage" channel="/chat" autoConnect="false" widgetVar="subscriber">
                <p:ajax event="message" update=":form:users" />
            </p:socket>

            <h3>Source</h3>
            <p:tabView>
                <p:tab title="chat.xhtml">
                    <pre name="code" class="xml">
&lt;p:growl id="growl" showDetail="true" /&gt;

&lt;h:form id="form"&gt;

    &lt;p:fieldset id="container" legend="PrimeChat" toggleable="true"&gt;

        &lt;h:panelGroup rendered="\#{chatView.loggedIn}"&gt;

            &lt;h:panelGrid columns="2" columnClasses="publicColumn,usersColumn" style="width:100%"&gt;
                &lt;p:outputPanel id="public" layout="block" styleClass="ui-corner-all ui-widget-content chatlogs"/&gt;

                &lt;p:dataList id="users" var="user" value="\#{chatUsers.users}" styleClass="usersList"&gt;
                    &lt;f:facet name="header"&gt;
                        Users
                    &lt;/f:facet&gt;

                    &lt;p:commandButton title="Chat" icon="ui-icon-comment" oncomplete="PF('pChat').show()" update=":form:privateChatContainer"&gt;
                        &lt;f:setPropertyActionListener value="\#{user}" target="\#{chatView.privateUser}" /&gt;
                    &lt;/p:commandButton&gt;
                    \#{user}
                &lt;/p:dataList&gt;
            &lt;/h:panelGrid&gt;

            &lt;p:separator /&gt;

            &lt;p:inputText value="\#{chatView.globalMessage}" styleClass="messageInput" /&gt;
            &lt;p:spacer width="5" /&gt;
            &lt;p:commandButton value="Send" actionListener="\#{chatView.sendGlobal}" oncomplete="$('.messageInput').val('').focus()"/&gt;
            &lt;p:spacer width="5" /&gt;
            &lt;p:commandButton value="Disconnect" actionListener="\#{chatView.disconnect}" global="false" update="container" /&gt;
        &lt;/h:panelGroup&gt;

        &lt;h:panelGroup rendered="\#{not chatView.loggedIn}" &gt;
            Username: &lt;p:inputText value="\#{chatView.username}" /&gt;

            &lt;p:spacer width="5" /&gt;
            &lt;p:commandButton value="Login" actionListener="\#{chatView.login}" update="container" 
                                icon="ui-icon-person" /&gt;
        &lt;/h:panelGroup&gt;

    &lt;/p:fieldset&gt;

    &lt;p:dialog widgetVar="pChat" header="Private Chat" modal="true" showEffect="fade" hideEffect="fade"&gt;
        &lt;h:panelGrid id="privateChatContainer" columns="2" columnClasses="vtop,vtop"&gt;
            &lt;p:outputLabel for="pChatInput" value="To: \#{chatView.privateUser}" /&gt;
            &lt;p:inputTextarea id="pChatInput" value="\#{chatView.privateMessage}" rows="5" cols="30" /&gt;

            &lt;p:spacer /&gt;
            &lt;p:commandButton value="Send" actionListener="\#{chatView.sendPrivate}" oncomplete="PF('pChat').hide()" /&gt;
        &lt;/h:panelGrid&gt;
    &lt;/p:dialog&gt;

&lt;/h:form&gt;

&lt;p:socket onMessage="handleMessage" channel="/chat" autoConnect="false" widgetVar="subscriber"/&gt;

&lt;script type="text/javascript"&gt;
    function handleMessage(data) {
        var chatContent = $(PrimeFaces.escapeClientId('form:public'));
        chatContent.append(data + '&lt;br /&gt;');

        //keep scroll
        chatContent.scrollTop(chatContent.height());
    }
&lt;/script&gt;
                    </pre>
                </p:tab>
                
                <p:tab title="ChatView.java">
                    <pre name="code" class="java">
package org.primefaces.examples.view;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import org.primefaces.context.RequestContext;
import org.primefaces.push.PushContext;
import org.primefaces.push.PushContextFactory;

public class ChatView {
    
    private final PushContext pushContext = PushContextFactory.getDefault().getPushContext();
    
    private ChatUsers users;

	private String privateMessage;
    
    private String globalMessage;
	
	private String username;
	
	private boolean loggedIn;
    
    private String privateUser;
    
    private final static String CHANNEL = "/chat/";

    public void setUsers(ChatUsers users) {
        this.users = users;
    }

    public String getPrivateUser() {
        return privateUser;
    }

    public void setPrivateUser(String privateUser) {
        this.privateUser = privateUser;
    }

    public String getGlobalMessage() {
        return globalMessage;
    }

    public void setGlobalMessage(String globalMessage) {
        this.globalMessage = globalMessage;
    }

    public String getPrivateMessage() {
        return privateMessage;
    }

    public void setPrivateMessage(String privateMessage) {
        this.privateMessage = privateMessage;
    }
    
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	
	public boolean isLoggedIn() {
		return loggedIn;
	}
	public void setLoggedIn(boolean loggedIn) {
		this.loggedIn = loggedIn;
	}

	public void sendGlobal() {
        pushContext.push(CHANNEL + "*", username + ": " + globalMessage);
		
		globalMessage = null;
	}
    
    public void sendPrivate() {
        pushContext.push(CHANNEL + privateUser, "[PM] " + username + ": " + privateMessage);
        
        privateMessage = null;
    }
	
	public void login() {
        RequestContext requestContext = RequestContext.getCurrentInstance();
        
		if(users.contains(username)) {
            loggedIn = false;
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Username taken", "Try with another username."));
            
            requestContext.update("growl");
        }
        else {
            users.addUser(username);
            pushContext.push(CHANNEL, username + " joined the channel.");
            requestContext.execute("subscriber.connect('/" + username + "')");
            loggedIn = true;
        }
	}
    
    public void disconnect() {
        //remove user and update ui
        users.removeUser(username);
        RequestContext.getCurrentInstance().update("form:users");
        
        //push leave information
        pushContext.push(CHANNEL, username + " left the channel.");
        
        //reset state
        loggedIn = false;
        username = null;
    }
}
                    </pre>
                </p:tab>
            </p:tabView>
		
		</div>
	</ui:define>
</ui:composition>
